<?PHP

namespace SDF\Lib\Dingtalk;

use SDF\Common\Cache;

/**
 * 钉钉相关接口
 * https://open-doc.dingtalk.com/docs/doc.htm?spm=a219a.7629140.0.0.aeeyq4&treeId=367&articleId=107549&docType=1
 * @package SMB\Dingtalk
 */
class Dingtalk{
    //微应用ID，必须与DingTalkPC.config的一致
    private $agentId = '130778730';

    //企业id：每个企业都拥有唯一的corpId。
    private $corpId = 'ding1c8679f21d5d76f835c2f4657eb6378f';

    //corpSecret是企业应用里面用于保障数据安全的“钥匙”，每一个应用都有一个独立的访问密钥，为了保证数据的安全，corpSecret务必不能泄漏。
    private $corpsecret = 'trv0UBDlF3uLEYEZfeUGbdnEdz1HMR75MRDauzusAfUJBS1Q5f9O3E9nVJKLH-nF';

    //用于生成签名的字符串，自己定义。
    private $nonceStr = 'abcdef';

    //private $access_token = '';

    //钉钉前端js Ticket，需要主动获取
    private $ticket = '';

    //时间戳，用来生成前端js相关的配置。
    private $timeStamp = null;

    //加解密需要用到的token，ISV(服务提供商)推荐使用注册套件时填写的token，普通企业可以随机填写
    private $token = 'abcdef';

    //数据加密密钥(ENCODING_AES_KEY)，注册事件回调接口中填写的数据加密密钥。用于回调数据的加解密，长度固定为43个字符，从a-z, A-Z, 0-9共62个字符中选取,您可以随机生成。
    private $aes_key = '11111111lvdhntotr3x9qhlbytb18zyz5z111111111';

    //钉钉扫码登陆使用的appid和appsecret，获取地址：http://open-dev.dingtalk.com/#/loginAndShareApp
    private $appid = 'dingoaogn5ewscs9by1kcy';
    private $appsecret = 'YBflmFdFpvlGkCwZdjNGz28FFwkptOo_jKNMNgFd9VLi4ltKPUiQPC1-rOVxqGDY';

    private $SSOsecret = 'bqxHqrL2PtSQp7jkmk_0yFZFjJkixVeZZaSOBFM7Qfo2TQJzG2VR2Q5BImX2niPx';
    private $ChannelSecret = '92ukrKIa6sp0yCLmuHQ0bJVZtaY8zIUS0tsU19FwqWooQQvnJuEi5SwI4TVRgRHr';

    //钉钉消息类型
    private $msgtype_arr = array(
        0 => 'text',
        1 => 'image',
        2 => 'voice',
        3 => 'file',
        4 => 'link',
        5 => 'oa'
    );

    /**
     * Dingtalk constructor.
     */
    public function __construct() {
        $this->timeStamp = time();
        if (class_exists('\DingtalkConf', false)) {
            $this->agentId = \DingtalkConf::AGENTID;
            $this->corpId = \DingtalkConf::CORPID;
            $this->corpsecret = \DingtalkConf::CORPSECRET;
            $this->nonceStr = \DingtalkConf::NONCESTR;
            $this->token = \DingtalkConf::TOKEN;
            $this->aes_key = \DingtalkConf::AES_KEY;
            $this->appid = \DingtalkConf::APPID;
            $this->appsecret = \DingtalkConf::APPSECRET;
            $this->SSOsecret = \DingtalkConf::SSOSECRET;
            $this->ChannelSecret = \DingtalkConf::CHANNELSECRET;
        }
        //$this->getAccessToken();
    }

    /**
     * 跳转到钉钉扫码登陆页面
     * @param $redirect_uri
     */
    public function gotoQrconnect($redirect_uri){
        //普通钉钉用户账号开放及免登:https://oapi.dingtalk.com/connect/oauth2/sns_authorize?appid=APPID&response_type=code&scope=snsapi_login&state=STATE&redirect_uri=REDIRECT_URI
        //网站应用钉钉扫码登录开发指南:https://oapi.dingtalk.com/connect/qrconnect?appid=APPID&response_type=code&scope=snsapi_login&state=STATE&redirect_uri=REDIRECT_URI
        $appid = $this->appid;
        $url = "https://oapi.dingtalk.com/connect/qrconnect?appid={$appid}&response_type=code&scope=snsapi_login&state=STATE&redirect_uri={$redirect_uri}";
        \header("Refresh:0;url={$url}");//301到钉钉的登陆扫码登陆页面。
        exit;
    }

    /**
     * 获取并缓存accessToken。accessToken有效期为两小时，需要在失效前请求新的accessToken
     * @return bool|null
     */
    private function getAccessToken(){
        $Cache = new Cache();
        $accessToken = $Cache->get('Dingtalk_corp_access_token');
        if(empty($accessToken)){
            $url = 'https://oapi.dingtalk.com/gettoken?corpid=' . $this->corpId . '&corpsecret=' . $this->corpsecret;
            $data = $this->http_curl($url);
            $accessToken = $data['access_token'];
            $Cache->set('Dingtalk_corp_access_token', $accessToken,7100);
        }
        return $accessToken;
    }

    /**
     * 获取钉钉开放应用的ACCESS_TOKEN
     * @return bool|mixed|null|string
     * @throws \Exception
     */
    private function getAppToken(){
        $Cache = new Cache();
        $CacheKey = 'DD_APP_TOKEN';
        $sns_token = $Cache->get($CacheKey);
        if(empty($sns_token)){
            $url = 'https://oapi.dingtalk.com/sns/gettoken?appid=' . $this->appid. '&appsecret=' . $this->appsecret;
            $data = $this->http_curl($url);
            if(!is_array($data) or $data['errcode'] > 0 or !isset($data['access_token'])){
                throw new \Exception('getAppToken error:'.$data['errmsg'],$data['errcode']);
            }
            $sns_token = $data['access_token'];
            $Cache->set($CacheKey, $sns_token,7100);
        }
        return $sns_token;
    }

    /**
     * 获取用户授权的SNS_TOKEN
     * @param string $app_token 开放应用的token
     * @param string $openid 用户的openid
     * @param string $persistent_code 用户授权给钉钉开放应用的持久授权码
     * @return bool|null
     * @throws \Exception
     */
    private function getSnsToken($app_token,$openid,$persistent_code){
        $Cache = new Cache();
        $CacheKey = 'DD_SNS_TOKEN_'.$persistent_code;
        $sns_token = $Cache->get($CacheKey);
        if(empty($sns_token)){
            $url = 'https://oapi.dingtalk.com/sns/get_sns_token?access_token=' . $app_token ;
            $post_data = array();
            $post_data['openid'] = $openid;
            $post_data['persistent_code'] = $persistent_code;
            $post_data = json_encode($post_data);
            $data = $this->post_curl($url, $post_data);
            if(!is_array($data) or $data['errcode'] > 0 or !isset($data['sns_token'])){
                throw new \Exception('getSnsToken error:'.$data['errmsg'],$data['errcode']);
            }
            $sns_token = $data['sns_token'];
            $Cache->set($CacheKey, $sns_token,7100);
        }
        return $sns_token;
    }

    /**
     * 获取用户授权的个人信息
     * @param string $sns_token    用户授权tock
     * @param $sns_token
     * @return mixed
     * @throws \Exception
     */
    private function getSnsUserInfo($sns_token) {
        $url = 'https://oapi.dingtalk.com/sns/getuserinfo?sns_token=' . $sns_token;
        $data = $this->http_curl($url);
        if(!is_array($data) or $data['errcode'] > 0 or !isset($data['user_info'])){
            throw new \Exception('getSnsUserInfo error:'.$data['errmsg'],$data['errcode']);
        }
        return $data['user_info'];
    }

    /**
     * 获取用户授权的持久授权码
     * @param string $app_token
     * @param string $tmp_auth_code 临时授权码
     * @return mixed
     * @throws \Exception
     */
    private function getPersistentCode($app_token,$tmp_auth_code) {
        $url = 'https://oapi.dingtalk.com/sns/get_persistent_code?access_token=' . $app_token;
        $post_data = array(
            'tmp_auth_code' => $tmp_auth_code,
        );
        $post_data = json_encode($post_data);
        $data = $this->post_curl($url, $post_data);
        if(!is_array($data) or $data['errcode'] > 0){
            throw new \Exception('getPersistentCode error:'.$data['errmsg'],$data['errcode']);
        }
        return $data;
    }


    /**
     * 钉钉http请求
     * @param $url
     * @return mixed
     * @throws \Exception
     */
    private function http_curl($url) {
        $ch = \curl_init();//初始化curl
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $output = curl_exec($ch);
        curl_close($ch);
        if($output === FALSE){
            throw new \Exception('curl http_curl defeated');
        }
        $ret = json_decode($output, true);
        return $ret;
    }

    /**
     * 钉钉post请求
     * @param $url
     * @param $json_post_data
     * @return mixed
     * @throws \Exception
     */
    private function post_curl($url, $json_post_data) {
        if(is_array($json_post_data)){
            $json_post_data = json_encode($json_post_data);
        }
        $ch = \curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-type: application/json;charset=UTF-8'));

        //禁止ssl验证
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

        // post数据
        curl_setopt($ch, CURLOPT_POST, 1);
        // post的变量
        curl_setopt($ch, CURLOPT_POSTFIELDS, $json_post_data);
        $output = curl_exec($ch);
        curl_close($ch);
        if($output === FALSE){
            throw new \Exception('curl post defeated');
        }
        $ret = json_decode($output, true);
        return $ret;
    }

    /**
     * 钉钉发送消息接口
     * @param array $user 发送人员(userid)
     * @param array $content 发送内容，格式为
     * 'text'=> ["content": "张三的请假申请"]
     * 'image'=> ["media_id": "MEDIA_ID"]
     * 'voice'=> [
                    "media_id": "MEDIA_ID",
                    "duration": "10"
                ]
     * 'file'=> [
                    "media_id": "MEDIA_ID",
                    "duration": "10"
                ]
     * 'link'=> [
                    "messageUrl": "http://s.dingtalk.com/market/dingtalk/error_code.php",
                    "picUrl":"@lALOACZwe2Rk",
                    "title": "测试",
                    "text": "测试"
                ]
     * 'OA'=> [
                "message_url": "http://dingtalk.com",
                "head": {
                    "bgcolor": "FFBBBBBB",
                    "text": "头部标题"
                },
                "body": {
                    "title": "正文标题",
                    "form": [
                    {
                        "key": "姓名:",
                        "value": "张三"
                    },
                    {
                        "key": "年龄:",
                        "value": "20"
                    },
                    {
                        "key": "身高:",
                        "value": "1.8米"
                    },
                    {
                        "key": "体重:",
                        "value": "130斤"
                    },
                    {
                        "key": "学历:",
                        "value": "本科"
                    },
                    {
                        "key": "爱好:",
                        "value": "打球、听音乐"
                    }
                    ],
                    "rich": {
                        "num": "15.6",
                        "unit": "元"
                    },
                    "content": "大段文本大段文本大段文本大段文本大段文本大段文本大段文本大段文本大段文本大段文本大段文本大段文本",
                    "image": "@lADOADmaWMzazQKA",
                    "file_count": "3",
                    "author": "李四 "
                }
              ]
     * @param int $msgtype 消息类型
     * 0 => 'text',
     * 1 => 'image',
     * 2 => 'voice',
     * 3 => 'file',
     * 4 => 'link',
     * 5 => 'oa'
     *
     * @return bool
     */
    public function send_message(array $user,array $content,$msgtype = 0) {
        //消息内容不能为空
        if (empty($content)) {
            return false;
        }
        //发送人不能为空
        if (empty($user)) {
            return false;
        }
        //获取消息类型，不能为空
        if (array_key_exists($msgtype, $this->msgtype_arr)) {
            $type = $this->msgtype_arr[$msgtype];
        } else {
            if (in_array($msgtype, $this->msgtype_arr)) {
                $type = $msgtype;
            }
        }
        if (empty($type)) {
            return false;
        }

        //发送人字符串
        $touser = '';
        foreach ($user as $u) {
            $touser .= $u . '|';
        }
        if (!empty($touser)) {
            $touser = substr($touser, 0, strlen($touser) - 1);
        }
        $access_token = $this->getAccessToken();
        $url = 'https://oapi.dingtalk.com/message/send?access_token=' . $access_token;
        $postdata = array();
        $postdata['touser'] = $touser;
        $postdata['agentid'] = $this->agentId;
        $postdata['msgtype'] = $type;
        $postdata[$type] = $content;
        $postdata = json_encode($postdata);
        $output = $this->post_curl($url, $postdata);
        return $output;
    }

    /**
     * 通过钉钉"用户扫码登录得到的code获取钉钉用户信息"
     * @param string $code
     * @return array|mixed
     * @throws \Exception
     */
    public function getUserDetailsByCode($code) {
        $code = trim($code);
        if (empty($code)) {
            throw new \Exception('code is null');
        }
        //获取钉钉开放应用的ACCESS_TOKEN
        $app_token = $this->getAppToken();

        //获取用户授权的持久授权码
        $data = $this->getPersistentCode($app_token,trim($code));
        $openid = $data['openid'];
        $persistent_code = $data['persistent_code'];

        //获取用户授权的SNS_TOKEN
        $sns_token = $this->getSnsToken($app_token,$openid,$persistent_code);

        //获取用户授权的个人信息
        $data = $this->getSnsUserInfo($sns_token);
        //$data['persistent_code'] = $persistent_code;
            /*
            [nick] => 袁吉
            [unionid] => AnoU8IRPR4aiP35dCiiKqLcAiEiE
            [dingId] => $:LWCP_v1:$ffCEeRs6Tmxq/I6bmT7Zhw==
            [openid] => SkCRwDe1sJkwiPiihjADd1FQiEiE
            */
        return $data;
        /*$unionid = $data['unionid'];
        //返回用户userid
        $userid = $this->getUnionidUserId($unionid);
        //返回用户相信信息
        $UserDetails = $this->getUserDetails($userid);
        return $UserDetails;*/
    }

    /**
     * 根据部门 id 获取部门详情
     * @param $department_id
     * @return array|mixed
     */
    public function getDepartmentDetails($department_id) {
        if(empty($department_id)) {
            return array();
        }
        $access_token = $this->getAccessToken();
        $url = 'https://oapi.dingtalk.com/department/get?access_token=' . $access_token . '&id=' . $department_id;
        $data = $this->http_curl($url);
        return $data;
    }

    /**
     * 创建部门
     * @param array $data
        data结构体：
        {
        "name": "钉钉事业部",
        "parentid": "1",
        "order": "1",
        "createDeptGroup": true,
        "deptHiding" : true,
        "deptPerimits" : "3|4",
        "userPerimits" : "userid1|userid2",
        "outerDept" : true,
        "outerPermitDepts" : "1|2",
        "outerPermitUsers" : "userid3|userid4"
        }
     * @return bool|mixed
     */
    public function createDepartment($data = array()) {
        if(empty($data)){
            return false;
        }
        $access_token = $this->getAccessToken();
        $url = 'https://oapi.dingtalk.com/department/create?access_token=' . $access_token;
        $ret = $this->post_curl($url,$data);
        return $ret;
    }

    /**
     * 修改部门信息
     * @param array $data
        结构体：
        {
        "name": "钉钉事业部",
        "parentid": "1",
        "order": "1",
        "id": "1",
        "createDeptGroup": true,
        "autoAddUser": true,
        "deptManagerUseridList": "manager1111|2222",
        "deptHiding" : true,
        "deptPerimits" : "3|4",
        "userPerimits" : "userid1|userid2",
        "outerDept" : true,
        "outerPermitDepts" : "1|2",
        "outerPermitUsers" : "userid3|userid4",
        "orgDeptOwner": "manager1111"
        }
     * @return bool|mixed
     */
    public function updateDepartment($data = array()) {
        if(empty($data)){
            return false;
        }
        $access_token = $this->getAccessToken();
        $url = 'https://oapi.dingtalk.com/department/update?access_token=' . $access_token;
        $ret = $this->post_curl($url,$data);
        return $ret;
    }

    /**
     * 获取钉钉前端js config
     * @return array
     */
    public function getConfig() {
        //获取jsapi_ticket
        $access_token = $this->getAccessToken();
        $this->getJsTicket($access_token);
        //获取signature
        $_url = $this->curPageURL();
        $signature = $this->sign($this->ticket, $this->nonceStr, $this->timeStamp, $_url);//签名处理
        $config = array(
            'url' => $_url,
            'nonceStr' => $this->nonceStr,
            'agentId' => $this->agentId,
            'timeStamp' => $this->timeStamp,
            'access_token' => $access_token,
            'corpId' => $this->corpId,
            'signature' => $signature
        );
        return $config;
    }

    /**
     * 获取钉钉前端js Ticket
     * @param $access_token
     * @return mixed
     */
    public function getJsTicket($access_token){
        //$access_token = $this->getAccessToken();
        $url = 'https://oapi.dingtalk.com/get_jsapi_ticket?access_token=' . $access_token;
        $data = $this->http_curl($url);
        $this->ticket = $data['ticket'];
        return $data;
    }

    /**
     * 签名
     * @param $ticket
     * @param $nonceStr
     * @param $timeStamp
     * @param $url
     * @return string
     */
    private function sign($ticket, $nonceStr, $timeStamp, $url) {
        $plain = 'jsapi_ticket=' . $ticket .
            '&noncestr=' . $nonceStr .
            '&timestamp=' . $timeStamp .
            '&url=' . $url;
        return sha1($plain);
    }

    /**
     * 获取当期页面的url地址
     * @return string
     */
    private function curPageURL() {
        $pageURL = 'http';

        if (array_key_exists('HTTPS', $_SERVER) && $_SERVER["HTTPS"] == "on") {
            $pageURL .= "s";
        }
        $pageURL .= "://";

//        if ($_SERVER["SERVER_PORT"] != "80") {
//            $pageURL .= $_SERVER["HTTP_HOST"] . ":" . $_SERVER["SERVER_PORT"] . $_SERVER["REQUEST_URI"];
//        } else {
            $pageURL .= $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"];
//        }
        return $pageURL;
    }

    /**
     * 根据code获取钉钉账户详情
     * @param string $code
     * @return array|mixed
     */
    public function getUserInfo($code) {
        $access_token = $this->getAccessToken();
        $url = 'https://oapi.dingtalk.com/user/getuserinfo?access_token=' . $access_token . '&code=' . $code;
        $data = $this->http_curl($url);
        /*$userid = $data['userid'];
        $data = $this->getUserDetails($userid);*/
        return $data;
    }

    /**
     * 根据用户的unionid获取userid
     * @param string $unionid
     * @return array
     */
    public function getUnionidUserId($unionid = '') {
        if (empty($unionid)) {
            return null;
        }
        $access_token = $this->getAccessToken();
        $url = 'https://oapi.dingtalk.com/user/getUseridByUnionid?access_token=' . $access_token . '&unionid=' . $unionid;
        $data = $this->http_curl($url);
        return $data;
    }

    /**
     * 根据钉钉userid 获取用户详情
     * @param string $userid
     * @return mixed
     */
    public function getUserDetails($userid = '') {
        $access_token = $this->getAccessToken();
        if (empty($userid)) {
            return array();
        }
        $url = 'https://oapi.dingtalk.com/user/get?access_token=' . $access_token . '&userid=' . $userid;
        $data = $this->http_curl($url);
        return $data;
    }

    /**
     * 获取所有钉钉用户
     * @param string $user_key
     * @return array
     */
    public function getAllUser($user_key = 'name') {
        $data = $this->getDepartmentList();//获取部门列表
        $user = array();
        if (isset($data['department'])) {
            foreach ($data['department'] as $vl) {
                $department_id = $vl['id'];
                //$url = 'https://oapi.dingtalk.com/user/simplelist?access_token=' . $access_token . '&department_id=' . $department_id;
                $department_user = $this->getDepartmentUserList($department_id);//$this->http_curl($url);
                if (isset($department_user['userlist'])) {
                    foreach ($department_user['userlist'] as $u) {
                        $user_data = $this->getUserDetails($u['userid']);
                        $user[trim($user_data[$user_key])] = $user_data;
                    }
                }
            }
        }
        return $user;
    }

    /**
     * 获取部门用户列表
     * @param $department_id
     * @return mixed
     */
    public function getDepartmentUserList($department_id){
        $access_token = $this->getAccessToken();
        $url = 'https://oapi.dingtalk.com/user/simplelist?access_token=' . $access_token . '&department_id=' . $department_id;
        $department_user = $this->http_curl($url);
        return $department_user;
    }

    /**
     * 获取部门列表
     * @return mixed
     */
    public function getDepartmentList(){
        $access_token = $this->getAccessToken();
        $url = 'https://oapi.dingtalk.com/department/list?access_token=' . $access_token;
        $data = $this->http_curl($url);
        return $data;
    }

    /**
     * 注册事件回调接口
     * @param $redirect_uri
     * @param array $call_back_tag
     * @return mixed
     */
    public function register_call_back($redirect_uri, array $call_back_tag) {
        $access_token = $this->getAccessToken();
        $url = "https://oapi.dingtalk.com/call_back/register_call_back?access_token=" . $access_token;
        $data = array();
        $data['token'] = $this->token;
        $data['aes_key'] = $this->aes_key;
        $data['url'] = $redirect_uri;//'https://admin.ismbao.com/login/call_back';
        $data['call_back_tag'] = $call_back_tag;
        /*$data['call_back_tag'][] = 'user_aorg';//通讯录用户增加
        $data['call_back_tag'][] = 'user_modify_org';//通讯录用户更改
        $data['call_back_tag'][] = 'user_leave_org';//通讯录用户离职
        $data['call_back_tag'][] = 'org_admin_add';//通讯录用户被设为管理员
        $data['call_back_tag'][] = 'org_admin_remove';//通讯录用户被取消设置管理员
        $data['call_back_tag'][] = 'org_dept_create';//通讯录企业部门创建
        $data['call_back_tag'][] = 'org_dept_modify';//通讯录企业部门修改
        $data['call_back_tag'][] = 'org_dept_remove';//通讯录企业部门删除
        $data['call_back_tag'][] = 'org_remove';//企业被解散
        $data['call_back_tag'][] = 'chat_amember';//群会话添加人员
        $data['call_back_tag'][] = 'chat_remove_member';//群会话删除人员
        $data['call_back_tag'][] = 'chat_quit';//群会话用户主动退群
        $data['call_back_tag'][] = 'chat_update_owner';//群会话更换群主
        $data['call_back_tag'][] = 'chat_update_title';//群会话更换群名称
        $data['call_back_tag'][] = 'chat_disband';//群会话解散群
        $data['call_back_tag'][] = 'chat_disband_microapp';//绑定了微应用的群会话，在解散时回调*/
        $post_data = json_encode($data);
        return $this->post_curl($url, $post_data);
    }

    /**
     * 更新钉钉事件接口
     * @param string $redirect_uri 事件回调url地址，例如：https://admin.ismbao.com/login/call_back
     * @param array $call_back_tag
     * @return mixed
     */
    public function update_call_back($redirect_uri, array $call_back_tag) {
        $access_token = $this->getAccessToken();
        $url = 'https://oapi.dingtalk.com/call_back/update_call_back?access_token=' . $access_token;
        $data = array();
        $data['token'] = $this->token;
        $data['aes_key'] = $this->aes_key;
        $data['url'] = $redirect_uri;//'https://admin.ismbao.com/login/call_back';
        $data['call_back_tag'] = array(
            /*'user_aorg',//通讯录用户增加
            'user_modify_org',//通讯录用户更改
            'user_leave_org',//通讯录用户离职*/
        );
        $data['call_back_tag'] += $call_back_tag;
//        $data['call_back_tag'][] = 'org_admin_add';//通讯录用户被设为管理员
//        $data['call_back_tag'][] = 'org_admin_remove';//通讯录用户被取消设置管理员
//        $data['call_back_tag'][] = 'org_dept_create';//通讯录企业部门创建
//        $data['call_back_tag'][] = 'org_dept_modify';//通讯录企业部门修改
//        $data['call_back_tag'][] = 'org_dept_remove';//通讯录企业部门删除
//        $data['call_back_tag'][] = 'org_remove';//企业被解散
//        $data['call_back_tag'][] = 'chat_amember';//群会话添加人员
//        $data['call_back_tag'][] = 'chat_remove_member';//群会话删除人员
//        $data['call_back_tag'][] = 'chat_quit';//群会话用户主动退群
//        $data['call_back_tag'][] = 'chat_update_owner';//群会话更换群主
//        $data['call_back_tag'][] = 'chat_update_title';//群会话更换群名称
//        $data['call_back_tag'][] = 'chat_disband';//群会话解散群
//        $data['call_back_tag'][] = 'chat_disband_microapp';//绑定了微应用的群会话，在解散时回调
        $post_data = json_encode($data);
        return $this->post_curl($url, $post_data);
    }

    /**
     * 获取回调失败的结果
     * @return mixed
     * @throws \Exception
     */
    public function get_call_back_failed_result() {
        $access_token = $this->getAccessToken();
        $url = 'https://oapi.dingtalk.com/call_back/get_call_back_failed_result?access_token=' . $access_token;
        $data = $this->http_curl($url);
        if(!is_array($data) or $data['errcode'] > 0){
            throw new \Exception('get_call_back_failed_result error:'.$data['errmsg'],$data['errcode']);
        }
        return $data;
    }


    /**
     * 接收钉钉事件回调消息，返回解密后的数据
     * @param string $signature 钉钉的加密签名，signature结合了开发者填写的token、请求中的timestamp、nonce参数、加密的消息体
     * @param string $timeStamp    时间戳
     * @param string $nonce    随机数
     * @param $encrypt
     * @return string
     */
    public function call_back($signature, $timeStamp, $nonce, $encrypt) {
        //日志信息
        $DingtalkCryptObj = new DingtalkCrypt($this->token, $this->aes_key, $this->corpId);
        //返回钉钉的成功信息
        $res = "success";
        $success_Msg = "";
        $DingtalkCryptObj->EncryptMsg($res, $timeStamp, $nonce, $success_Msg);
        try {
            $ret = array();
            $DingtalkCryptObj->DecryptMsg($signature, $timeStamp, $nonce, $encrypt, $ret);
            $ret = json_decode($ret, true);
            return $ret;
            //获取回调监听事件
            /*$interface = @$ret['EventType'];
            $interface_success = false;
            if (method_exists($this, $interface)) {
                $interface_success = $this->$interface($ret);
            }
            return $interface_success;*/
        } catch (\Exception $e) {

        } finally {
            return $success_Msg;
        }
    }
}